package com.make.house.api.controller.wxcontroller.login;

import com.make.house.api.common.ECConstant;
import com.make.house.api.common.HttpClient;
import com.make.house.api.common.SnowflakeIdWorker;
import com.make.house.api.entity.user.UserAuthEntity;
import com.make.house.api.entity.user.UserEntity;
import com.make.house.api.model.ActionStatus;
import com.make.house.api.model.JSONResult;
import com.make.house.api.model.UserLoginIdentityType;
import com.make.house.api.repository.user.UserAuthRepository;
import com.make.house.api.repository.user.UserRepository;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created by yanglinlong on 18/8/15.
 * 微信登录Controller
 */

@RestController
@RequestMapping(ECConstant.API_REQUEST_WX_URL+"/user")
@Api("微信小程序登录")
public class WxUserController {

    private static Logger logger = LoggerFactory.getLogger(WxUserController.class);
    @Autowired
    private HttpClient httpClient;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UserAuthRepository userAuthRepository;

    public static final String WX_CHEKC_URL = "https://api.weixin.qq.com/sns/jscode2session?" +
            "appid=%1$s&secret=%2$s&js_code=%3$s&grant_type=authorization_code";

    @ApiOperation(value="小程序登录", notes="小程序登录", response = WxLoginRespneseBean.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "wx_code", value = "微信code", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "appid", value = "小程序appid", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "secret", value = "小程序secret", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "user_name", value = "用户名", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "avatar", value = "用户头像url", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "sex", value = "性别 0男 1女", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "platform", value = "平台(Android或iOS)", required = false, dataType = "String", paramType = "query")
    })
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public JSONResult loginEngineer(WxLoginRequestParams params) {
        if (params != null) {
            //api url地址
            String url = String.format(WX_CHEKC_URL, params.getAppid(), params.getSecret(), params.getWx_code());
            //post请求
            HttpMethod method = HttpMethod.POST;
            // 封装参数，千万不要替换为Map与HashMap，否则参数无法传递
            MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>();
            //发送http请求并返回结果
            String result = httpClient.client(url, method, map);

            org.json.JSONObject jsResult = new org.json.JSONObject(result);
            if (jsResult.has("errcode")){
                //获取code失败
                return JSONResult.newBuilder().setStatus(ActionStatus.WX_LOGIN_FAIL.inValue())
                        .setDesc("errcode: " + jsResult.optInt("errcode") + "\n" + "errmsg:"+ jsResult.optString("errmsg"))
                        .build();
            }else {
                //获取session_key 成功
                WxLoginRespneseBean respneseBean = new WxLoginRespneseBean();
                respneseBean.setOpenid(jsResult.optString("openid"));
                respneseBean.setUnionid(jsResult.optString("unionid"));
                respneseBean.setSession_key(jsResult.optString("session_key"));

                UserEntity userEntity;
                UserAuthEntity userAuthEntity = userAuthRepository.findByIdentifierAndIdentityType(respneseBean.getOpenid(), UserLoginIdentityType.WX_MINIPROGRAM);
                if (userAuthEntity == null){ //未注册 先注册
                    userAuthEntity = new UserAuthEntity();
                    userAuthEntity.setUid(String.valueOf(new SnowflakeIdWorker(0, 0).nextId()));
                    userAuthEntity.setIdentityType(UserLoginIdentityType.WX_MINIPROGRAM);
                    userAuthEntity.setIdentifier(respneseBean.getOpenid());
                    userAuthEntity.setPasswordText(jsResult.optString("session_key"));
                    userAuthEntity.setRegisterTime(System.currentTimeMillis());
                    userAuthEntity.setLastLoginTime(System.currentTimeMillis());
                    userAuthEntity.setPlatform(params.getPlatform());
                    userAuthEntity.setLoginStatus(1);

                    userEntity = new UserEntity();
                    userEntity.setUid(userAuthEntity.getUid());
                }else {
                    //已注册
                    userAuthEntity.setPasswordText(jsResult.optString("session_key"));
                    userAuthEntity.setLastLoginTime(System.currentTimeMillis());
                    userAuthEntity.setPlatform(params.getPlatform());
                    userAuthEntity.setLoginStatus(1);

                    userEntity = userRepository.findByUid(userAuthEntity.getUid());
                }
                // 保存或更新用户信息
                userEntity.setNickname(params.getUser_name());
                userEntity.setAvatar(params.getAvatar());
                userEntity.setSex(params.getSex());
                userRepository.save(userEntity);
                userAuthRepository.save(userAuthEntity);

                respneseBean.setUid(userEntity.getUid());
                logger.debug("小程序登录验证请求结果：" + result);
                return JSONResult.newBuilder().setStatus(ActionStatus.NORMAL_RETURNED.inValue())
                        .setDesc(ActionStatus.NORMAL_RETURNED.getDescription())
                        .setData(respneseBean).build();
            }
        }

        return JSONResult.paramErrorResult("参数错误");

    }

}
